<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2011 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: luofei614 <weibo.com/luofei614>　
// +----------------------------------------------------------------------
namespace Kcdns\Common\Common;

class AuthExtend extends \Think\Auth
{
    // url链接类型
    const RULE_TYPE_URL = 1;
    
    // 主菜单类型
    const RULE_TYPE_MAIN = 2;
    
    // 获取指定用户的权限列表
    public function getAuthList ($uid, $type)
    {
        static $_authList = array(); // 保存用户验证通过的权限列表
        $t = implode(',', (array) $type);
        if (isset($_authList[$uid . $t]))
        {
            return $_authList[$uid . $t];
        }
        if ($this->_config['AUTH_TYPE'] == 2 && isset($_SESSION['_AUTH_LIST_' . $uid . $t]))
        {
            return $_SESSION['_AUTH_LIST_' . $uid . $t];
        }
        
        if (IS_ROOT)
        {
            // 超级管理员拥有所有节点权限
            $map = array(
                    'type' => $type,
                    'status' => 1
            );
        }
        else
        {
            // 读取用户所属用户组
            $groups = $this->getGroups($uid);
            $ids = array(); // 保存用户所属用户组设置的所有权限规则id
            foreach ($groups as $g)
            {
                $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
            }
            $ids = array_unique($ids);
            if (empty($ids))
            {
                $_authList[$uid . $t] = array();
                return array();
            }
            
            $map = array(
                    'id' => array(
                            'in',
                            $ids
                    ),
                    'type' => $type,
                    'status' => 1
            );
        }
        // 读取用户组所有权限规则
        $rules = M()->table($this->_config['AUTH_RULE'])->where($map)->field('condition,name')->select();
        
        // 循环规则，判断结果。
        $authList = array(); //
        foreach ($rules as $rule)
        {
            if (! empty($rule['condition']))
            { // 根据condition进行验证
                $user = $this->getUserInfo($uid); // 获取用户信息,一维数组
                
                $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);
                // dump($command);//debug
                @(eval('$condition=(' . $command . ');'));
                if ($condition)
                {
                    $authList[] = strtolower($rule['name']);
                }
            }
            else
            {
                // 只要存在就记录
                $authList[] = strtolower($rule['name']);
            }
        }
        $_authList[$uid . $t] = $authList;
        if ($this->_config['AUTH_TYPE'] == 2)
        {
            // 规则列表结果保存到session
            $_SESSION['_AUTH_LIST_' . $uid . $t] = $authList;
        }
        return array_unique($authList);
    }

    /**
     * 找到指定链接的菜单 返回false 或 匹配到的菜单ID
     */
    public function findMenu ($url = null)
    {
        return;
        $url = $url ?  : (MODULE_NAME . '/' . CONTROLLER_NAME . '/' . ACTION_NAME . '?' . http_build_query(I('get.')));
        $cacheKey = 'af' . $url;
        $r = S($url);
        if (! $r)
        {
            do
            {
                $authRuleName = checkRule($url);
                if ($authRuleName === false)
                {
                    $r['r'] = false;
                    break;
                }
                
                // 清除authrule模块名 进行菜单匹配
                $authRuleName = str_replace('admin/', '', $authRuleName);
                $where = array(
                        'pid' => array(
                                'neq',
                                0
                        ),
                        'url' => $authRuleName,
                        'status' => 1
                );
                is_administrator() or $where['is_dev'] = 0;
                $menu = M('Menu')->where($where)->find();
                if (! $menu)
                {
                    $r['r'] = false;
                    break;
                }
                
                $r['r'] = $menu;
            }
            while (0);
            
            S($cacheKey, $r);
        }
        return $r['r'];
    }

    /**
     * 找到指定规则的层级路径(递归)
     */
    public function findRulePath ($menus, $ruleId, &$currentPath = array())
    {
        return;
        foreach ($menus as $v)
        {
            $v['url'] = U($v['url']);
            if ($v['id'] == $ruleId)
            {
                if ($v['pid'] == 0)
                {
                    array_unshift($currentPath, $v);
                }
                else
                {
                    if ($v['group'])
                    {
                        $group = array(
                                'title' => $v['group'],
                                'url' => '#',
                                'hide' => $v['hide'],
                                'is_group' => true
                        );
                    }
                    array_unshift($currentPath, $v);
                    $group && array_unshift($currentPath, $group);
                    $this->findRulePath($menus, $v['pid'], $currentPath);
                }
            }
        }
        return $currentPath;
    }
    
    // 将url解析成 基础rule和参数两部分信息
    public function parseUrlRule ($url, $module = null)
    {
        return;
        $urlInfo = parse_url($url);
        $baseInfo = explode('/', $urlInfo['path']);
        $queryInfo = $urlInfo['query'] ? explode('&', $urlInfo['query']) : array();
        // 解析规则
        $rule = array();
        $rule['a'] = array_pop($baseInfo) ?  : ACTION_NAME;
        $rule['c'] = array_pop($baseInfo) ?  : CONTROLLER_NAME;
        $rule['m'] = array_pop($baseInfo) ?  : ($module ? $module : MODULE_NAME);
        // 解析参数
        $query = array();
        foreach ($queryInfo as $item)
        {
            $param = explode('=', $item);
            $query[$param[0]] = is_null($param[1]) ? "" : $param[1];
        }
        ksort($query);
        return array(
                'rule' => $rule['m'] . '/' . $rule['c'] . '/' . $rule['a'],
                'query' => $query
        );
    }
    
    // 检测解析后的当前规则节点与目标规则节点是否匹配 匹配失败 返回false 匹配成功 返回匹配到的参数个数 可能为0
    public function checkNodeRule ($currentRuleInfo = array(), $targetRuleInfo = array())
    {
        return;
        $paramMatchedCount = 0;
        if (strtolower($currentRuleInfo['rule']) !== strtolower($targetRuleInfo['rule']))
        {
            return false;
        }
        // 节点无参数权限规则 匹配成功
        if (! $targetRuleInfo['query'])
        {
            return $paramMatchedCount;
        }
        // 还有参数权限规则 参数需要完全匹配
        foreach ($targetRuleInfo['query'] as $authRuleQuery => $queryVal)
        {
            if (! isset($currentRuleInfo['query'][$authRuleQuery]) || $currentRuleInfo['query'][$authRuleQuery] !== $queryVal)
            {
                // 参数匹配未通过
                return false;
            }
            else
            {
                $paramMatchedCount ++;
            }
        }
        return $paramMatchedCount;
    }
    
    // 获取主菜单
    public function getMainMenus ()
    {
        is_administrator() or $where['is_dev'] = 0;
        $where['pid'] = 0;
        $where['hide'] = 0;
        $where['status'] = 1;
        return M('Menu')->where($where)->order('sort asc')->select();
    }
    
    // 缓存权限相关数据
    public function cacheAuth ($key, $data)
    {}
}
